﻿
using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using GruntXProductions;
using Viper;
using Viper.Opcodes;

namespace Diamond
{
    public partial class CodeGen
    {
        public void DeclareVar(Declaration decl)
        {
            if (decl.Type == "int")
                Symbols.DeclareInt32(decl.Name);
            else if (decl.Type == "string")
                Symbols.DeclareString(decl.Name);
            else if (decl.Type == "bool")
                Symbols.DeclareBool(decl.Name);
            else if (decl.Type == "var")
            {
                VType type = GuessType(decl.Value);
                if (type == VType.Dword)
                    Symbols.DeclareInt32(decl.Name);
                else if (type == VType.String)
                    Symbols.DeclareString(decl.Name);
                else if (type == VType.Boolean)
                    Symbols.DeclareBool(decl.Name);
                else
                    Errors.Add("Could not implicitly declare variable " + decl.Name);
            }
            else
            {
                Errors.Add("Unknown type '" + decl.Type + "'");
            }
        }
        public void DeclareArgument(Declaration decl)
        {
            if (decl.Value.Items.Count != 0)
                Errors.Add("Can not assign value to method argument!");
            DeclareVar(decl);
            if (decl.Type == "string" || decl.Type == "int" || decl.Type == "float")
            {
                Assembler.Emit(new push_ptr(Symbols[decl.Name]));
                Assembler.Emit(new dstore());
            }
        }
        public void Assign(string name, Expression exp)
        {
            if (Symbols.GetType(name) == VType.Dword)
            {
                ParseArthemeticExpression(exp);
                Assembler.Emit(new push_ptr(Symbols[name]));
                Assembler.Emit(new dstore());
            }
            else if (Symbols.GetType(name) == VType.Boolean)
            {
                ParseBooleanExpression(exp);
                Assembler.Emit(new push_ptr(Symbols[name]));
                Assembler.Emit(new dstore());
            }
            else if (Symbols.GetType(name) == VType.String)
            {
                ParseStringExpression(exp);
                Assembler.Emit(new push_ptr(Symbols[name]));
                Assembler.Emit(new dstore());
            }
            else if (Symbols.GetType(name) == VType.NotFound)
            {
                Errors.Add(name + " does not exist in the current context!");
            }

        }
        public void DeclareVarAndAssign(Declaration decl)
        {
            DeclareVar(decl);
            if (decl.Value.Items.Count == 0)
                return;
            else
                Assign(decl.Name, decl.Value);
        }
    }

}